#pragma once

#include <iostream>
#include <string>
#include <cstdlib>
#include <pthread.h>

using namespace std;

class Thread{
public:
    typedef enum{
        NEW = 0,
        RUNNING,
        EXITED
    } ThreadStatus;

    typedef void (*func_t)(void*);

    Thread(int num, func_t func, void *args)
        : _tid(0),
          _status(NEW),
          _func(func),
          _args(args){
        char name[128];
        snprintf(name, sizeof(name), "thread-%d", num);
        _name = name;
    }

    int status(){
        return _status;
    }

    string threadName(){
        return _name;
    }

    pthread_t threadId(){
        if(_status == RUNNING)
            return _tid;
        else
            return 0;
    }

    static void* runHelper(void* args){
        Thread *tp = (Thread*)args;
        if((tp->_func) != nullptr)
            tp->_func(tp->_args);
        return nullptr;
    }

    void run(){
        int n = pthread_create(&_tid, nullptr, runHelper, this);
        if(n != 0)
            exit(1);
        _status = RUNNING;
    }

    void join(){
        int n = pthread_join(_tid, nullptr);
        if( n != 0){
            cerr << "main thread join thread " << _name << " error" << endl;
            return;
        }
        _status = EXITED;
    }

    ~Thread(){

    }

private:
    pthread_t _tid;
    string _name;
    func_t _func;
    void *_args;
    ThreadStatus _status;
};